package com.clp.protocol.iec104.apdu.asdu.infoobj.infoelem.filetransfer;

import com.clp.protocol.iec104.definition.ConstVal;
import com.clp.protocol.iec104.definition.Ft;
import com.clp.protocol.core.utils.ByteUtil;
import com.clp.protocol.core.utils.StringUtil;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Objects;

/**
 * 读文件激活确认 附加数据包
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class FileReadConAttachPack extends AttachPack {
    @Override
    public Ft.OperationTag operationTag() {
        return Ft.OperationTag.FILE_READ_CON;
    }

    /**
     * 结果描述字
     */
    private Ft.FileReadConRD fileReadConRD;
    /**
     * 文件名长度（字节）
     */
    private int filenameBytesLen;
    /**
     * 文件名
     */
    private String filename;
    /**
     * 文件id
     */
    private long fileId;
    /**
     * 文件大小(字节)
     */
    private long fileSize;

    @Override
    public FileReadConAttachPack refreshFrom(ByteBuf buf) {
        checkOperationTag(buf.readByte());
        // 结果描述字
        this.fileReadConRD = Ft.FileReadConRD.gain(buf.readByte());
        // 文件名长度
        this.filenameBytesLen = buf.readByte() & 0xFF;
        // 文件名
        byte[] filenameBytes = new byte[filenameBytesLen]; buf.readBytes(filenameBytes);
        this.filename = StringUtil.decode(filenameBytes, "utf-8");
        // 文件id
        byte[] fileIdBytes = new byte[ConstVal.FILE_ID_LEN]; buf.readBytes(fileIdBytes);
        this.fileId = ByteUtil.bytes4ToLongLE(fileIdBytes);
        // 文件大小
        byte[] fileSizeBytes = new byte[ConstVal.FILE_SIZE_LEN]; buf.readBytes(fileSizeBytes);
        this.fileSize = ByteUtil.bytes4ToLongLE(fileSizeBytes);
        return this;
    }

    @Override
    public boolean isValid() {
        if (fileReadConRD == null) return false;
        if (filenameBytesLen < 0 || filenameBytesLen > 0xFF) return false;
        if (filename == null || filename.equals("")) return false;
        if (fileId < 0 || fileId > 0xFFFFFFFFL) return false;
        return fileSize >= 0 && fileSize <= 0xFFFFFFFFL;
    }

    @Override
    public void writeBytesTo(ByteBuf buf) {
        // 填写操作标识
        buf.writeByte(operationTag().getVal());
        // 结果描述字
        buf.writeByte(fileReadConRD.getVal());
        // 文件名长度
        byte[] filenameBytes = StringUtil.encode(filename, "utf-8");
        buf.writeByte(filenameBytes.length);
        // 文件名
        buf.writeBytes(filenameBytes);
        // 文件id
        buf.writeBytes(ByteUtil.longToBytes4LE(fileId));
        // 文件大小
        buf.writeBytes(ByteUtil.longToBytes4LE(fileSize));
    }

    @Override
    public String toString() {
        // TODO 暂时这样
        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FileReadConAttachPack that = (FileReadConAttachPack) o;
        return filenameBytesLen == that.filenameBytesLen && fileId == that.fileId && fileSize == that.fileSize && fileReadConRD == that.fileReadConRD && Objects.equals(filename, that.filename);
    }

    @Override
    public int hashCode() {
        return Objects.hash(fileReadConRD, filenameBytesLen, filename, fileId, fileSize);
    }
}
